//
//  AccelerationAppDelegate.m
//  Acceleration
//
//  Created by Chris Whitney on 11/11/08.
//  Copyright __MyCompanyName__ 2008. All rights reserved.
//

#import "AccelerationAppDelegate.h"

// Constant for the number of times per second (Hertz) to sample acceleration.
#define kAccelerometerFrequency 40

// Constant for the number of acceleration samples (kAccelerometerFrequency) before updating the volume
#define kVolumeUpdateInterval  200

// Acceleration history
float accelerationHistory[kVolumeUpdateInterval][3];
int numActivitySamples = 0;

@implementation AccelerationAppDelegate

@synthesize window;
@synthesize filterButton, recordButton;
@synthesize xGraphView, yGraphView, zGraphView;
@synthesize data;
@synthesize volumeControl;

- (void)applicationDidFinishLaunching:(UIApplication *)application {    
    
    // Set default state
    isRecording = FALSE;
    isFiltering = FALSE;
    
    xGraphView.axisNumber = 0;
    yGraphView.axisNumber = 1;
    zGraphView.axisNumber = 2;
    
    // Override point for customization after application launch
    [window makeKeyAndVisible];
    
    // Configure and start the accelerometer
    [[UIAccelerometer sharedAccelerometer] setUpdateInterval:(1.0 / kAccelerometerFrequency)];
    [[UIAccelerometer sharedAccelerometer] setDelegate:self];
    
    // Initialize data logging
    self.data = [NSMutableData dataWithCapacity:100];

    // Setup system volume controller using the Celestial private framework
    volumeControl = [[AVSystemController alloc] init];
    
    // Get current system volume
    [volumeControl getActiveCategoryVolume:(&currentVolume) andName:nil];
    
    // Start graph views
    xGraphView.updatingIsEnabled = yGraphView.updatingIsEnabled = zGraphView.updatingIsEnabled = true;
}


// UIAccelerometerDelegate method, called when the device accelerates.
- (void)accelerometer:(UIAccelerometer *)accelerometer didAccelerate:(UIAcceleration *)acceleration {
    // Update the accelerometer graph view
    [xGraphView updateHistoryWithValue:acceleration.x];
    [yGraphView updateHistoryWithValue:acceleration.y];
    [zGraphView updateHistoryWithValue:acceleration.z];
    
    // Write data to file
    if(isRecording) {
        NSString *triple = [NSString stringWithFormat:@"%f, %f, %f\n", acceleration.x, acceleration.y, acceleration.z];

        [data appendData:[triple dataUsingEncoding:NSUTF8StringEncoding]];
    }
    
    // Update activity
    if(numActivitySamples >= kVolumeUpdateInterval) {
        [self updateVolumeWithActivity:calcActivityLevel(accelerationHistory, kVolumeUpdateInterval)];
    }
    numActivitySamples %= kVolumeUpdateInterval;
    accelerationHistory[numActivitySamples][0] = acceleration.x;
    accelerationHistory[numActivitySamples][1] = acceleration.y;
    accelerationHistory[numActivitySamples][2] = acceleration.z;
    numActivitySamples++;
}


// Called when record button is hit
- (void)toggleRecord:(id)sender {
    if(isRecording) {
        // Transition to stopped
        [recordButton setStyle:UIBarButtonItemStyleBordered];
        [recordButton setTitle:@"Start Recording"];
    } else {
        // Transition to recording
        [recordButton setStyle:UIBarButtonItemStyleDone];
        [recordButton setTitle:@"Stop Recording"];
    }
    
    // Write data
    if(isRecording) {
        [self writeData];
    }

    isRecording = !isRecording;
}

// Called when filter button is hit
- (void)toggleFilter:(id)sender {
    if(isFiltering) {
        // Transition to not filtering
        [filterButton setStyle:UIBarButtonItemStyleBordered];
        [filterButton setTitle:@"Enable Filter"];
    } else {
        // Transition to filtering
        [filterButton setStyle:UIBarButtonItemStyleDone];
        [filterButton setTitle:@"Disable Filter"];
    }
    isFiltering = !isFiltering;
    
    // Update graph view
    xGraphView.filteringIsEnabled = yGraphView.filteringIsEnabled = zGraphView.filteringIsEnabled = isFiltering;
}

-(void)applicationWillTerminate:(UIApplication *)application {
    if(isRecording) {
        [self writeData];
    }
}

- (void)dealloc {
    [xGraphView release];
    [yGraphView release];
    [zGraphView release];
        
    [data release];
    [volumeControl release];
    
    [filterButton release];
    [recordButton release];
    [window release];
    [super dealloc];
}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
    
    // Attempt to free memory by writing to disk and releasing

    [self writeData];
    
    [self.data release];
    self.data = [NSMutableData dataWithCapacity:100];
    
    // Show an alert for debugging puposes
    UIAlertView *alert = [UIAlertView alloc];
    [alert initWithTitle:@"Memory Warning" message:@"Low memory!" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
    [alert show];
}


-(void)writeData {
    NSString *fullFilePath = [@"/tmp" stringByAppendingFormat:@"/%@.csv", [[NSDate date] description]];
    [data writeToFile:fullFilePath atomically:NO];
}


-(void)updateVolumeWithActivity:(int)activity {
    
    // Calculated new volume
    float volume = ((float) activity) / MAX_ACTIVITY;
    
    // Current volume (could have changed do to manual buttons, so fetch this value)
    [volumeControl getActiveCategoryVolume:(&currentVolume) andName:nil];
    
    // Updating volume will show the HUD, so only do it if the volume actually changed
    if(fabs(volume - currentVolume) > (1.0 / MAX_ACTIVITY)) {
        
        // Note: use [UIApp setSystemVolumeHUDEnabled:(BOOL)] to disable HUD, should be on by default
        [volumeControl setActiveCategoryVolumeTo:volume];
    }
    
}

@end
